package io.renren.modules.finance.service.impl;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.renren.common.base.GenericServiceImpl;
import io.renren.common.exception.RRException;
import io.renren.common.utils.*;
import io.renren.modules.finance.dao.FinanceWithdrawalsAppDao;
import io.renren.modules.finance.entity.UserMoneyTotal;
import io.renren.modules.finance.entity.FinanceMoneyRecord;
import io.renren.modules.finance.entity.FinanceWithdrawalsApp;
import io.renren.modules.finance.service.FinanceMoneyRecordService;
import io.renren.modules.finance.service.UserMoneyTotalService;
import io.renren.modules.finance.service.FinanceWithdrawalsAppService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import static io.renren.modules.finance.entity.FinanceMoneyRecord.TYPE_BALANCE;

/**
 * 代理提现申请
 *
 * @author meishou
 * @date 2019-05-02 14:36:34
 */
@Service("financeWithdrawalsAppService")
public class FinanceWithdrawalsAppServiceImpl extends GenericServiceImpl<FinanceWithdrawalsAppDao, FinanceWithdrawalsApp> implements FinanceWithdrawalsAppService {
    @Autowired
    private FinanceMoneyRecordService financeMoneyRecordService;
    @Autowired
    private UserMoneyTotalService agentMoneyTotalService;


    /**
     * 代理进行提现申请
     *
     * @return
     */
    @Override
    @Transactional
    public boolean apply(FinanceWithdrawalsApp financeWithdrawalsApp, UserMoneyTotal agentMoneyTotal) {
        financeWithdrawalsApp.setSn(Utils.getOrderNo());
        financeWithdrawalsApp.setCreateTime(DateUtil.date());
        financeWithdrawalsApp.setStatus(FinanceWithdrawalsApp.STATUS_AUDIT);
        financeWithdrawalsApp.setCreateTime(DateUtil.date());
        financeWithdrawalsApp.setModifyTime(DateUtil.date());
        String briefing = "提现支出：提现金额：" + financeWithdrawalsApp.getAmount() + "元";

        BigDecimal before = agentMoneyTotal.getBalanceIncome();
        BigDecimal after = agentMoneyTotal.getBalanceIncome().subtract(financeWithdrawalsApp.getAmount());
        if (after.compareTo(BigDecimal.ZERO) < 0) {
            try {
                throw new Exception("代理提现账户余额不足!");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        //添加记录
        FinanceMoneyRecord agentMoneyRecordEntity = new FinanceMoneyRecord();
        agentMoneyRecordEntity.setUserId(financeWithdrawalsApp.getUserId());
        agentMoneyRecordEntity.setChangeItem(FinanceMoneyRecord.CHANGE_ITEM_12);
        agentMoneyRecordEntity.setOperatorStyle(0);
        agentMoneyRecordEntity.setBriefing(briefing);
        agentMoneyRecordEntity.setChangeAmount(BigDecimal.ZERO.subtract(financeWithdrawalsApp.getAmount()));
        agentMoneyRecordEntity.setBeforeAmount(before);
        agentMoneyRecordEntity.setCurrentAmount(after);
        agentMoneyRecordEntity.setType(TYPE_BALANCE);
        agentMoneyRecordEntity.setCreateTime(DateUtils.getCurrentDate());
        agentMoneyRecordEntity.setModifyTime(DateUtils.getCurrentDate());
        financeMoneyRecordService.save(agentMoneyRecordEntity);
        //更新用戶鎖定金額
        agentMoneyTotal.setWithdrawLockMoney(StringUtil.nullToBigDecimal(agentMoneyTotal.getWithdrawLockMoney()).add(financeWithdrawalsApp.getAmount()));
        agentMoneyTotal.setBalanceIncome(after);
        agentMoneyTotalService.updateById(agentMoneyTotal);
        return baseMapper.insert(financeWithdrawalsApp) >= 1;

    }


    /**
     * 查询列表
     *
     * @param params
     * @return
     */
    @Override
    public PageUtils queryListPage(Map<String, Object> params) {
        Query<FinanceWithdrawalsApp> query = new Query<>();
        List<FinanceWithdrawalsApp> bookUserList = baseMapper.queryPage(query.getPage(params), params);
        query.getPage(params).setRecords(bookUserList);
        return new PageUtils(query.getPage(params));
    }

    /**
     * 同意
     *
     * @param
     * @param operatorId
     * @return
     */
    @Override
    @Transactional(rollbackFor = RRException.class)
    public boolean agree(FinanceWithdrawalsApp financeWithdrawalsApp, Integer operatorId) {
        //更改充值申请表
        financeWithdrawalsApp.setStatus(FinanceWithdrawalsApp.STATUS_SUCCESS);
        financeWithdrawalsApp.setOperateTime(new Date());
        financeWithdrawalsApp.setOperatorId(operatorId);
        baseMapper.updateById(financeWithdrawalsApp);
        //更改用户金额总表
        UserMoneyTotal agentMoneyTotal = agentMoneyTotalService.getByUserId(financeWithdrawalsApp.getUserId());
        agentMoneyTotal.setWithdrawLockMoney(agentMoneyTotal.getWithdrawLockMoney().subtract(financeWithdrawalsApp.getAmount()));
        agentMoneyTotal.setWithdrawTotal(agentMoneyTotal.getWithdrawTotal().add(financeWithdrawalsApp.getAmount()));
        agentMoneyTotalService.updateById(agentMoneyTotal);
        return true;
    }

    /**
     * 提现取消，用户操作
     *
     * @param financeWithdrawalsApp
     * @return
     */
    @Override
    @Transactional(rollbackFor = RRException.class)
    public boolean close(FinanceWithdrawalsApp financeWithdrawalsApp) {
        financeWithdrawalsApp.setStatus(FinanceWithdrawalsApp.STATUS_CLOSE);
        financeWithdrawalsApp.setOperateTime(new Date());
        UserMoneyTotal agentMoneyTotal = agentMoneyTotalService.getByUserId(financeWithdrawalsApp.getUserId());
        String briefing = "代理商提现返还 — 代理取消提现";
        closeFinanceApp(financeWithdrawalsApp, agentMoneyTotal, briefing);
        return true;
    }

    /**
     * 拒绝提现申请，后台操作
     *
     * @param financeWithdrawalsApp
     * @param
     * @return
     */
    @Override
    @Transactional(rollbackFor = RRException.class)
    public boolean reject(FinanceWithdrawalsApp financeWithdrawalsApp) {
        financeWithdrawalsApp.setStatus(FinanceWithdrawalsApp.STATUS_REJECT);
        financeWithdrawalsApp.setOperateTime(new Date());
        UserMoneyTotal agentMoneyTotal = agentMoneyTotalService.getByUserId(financeWithdrawalsApp.getUserId());
        String briefing = "代理商提现返还 — 总部拒绝提现";
        closeFinanceApp(financeWithdrawalsApp, agentMoneyTotal, briefing);
        return true;
    }


    private void closeFinanceApp(FinanceWithdrawalsApp financeWithdrawalsApp, UserMoneyTotal agentMoneyTotal, String briefing) {
        //添加记录
        FinanceMoneyRecord agentMoneyRecordEntity = new FinanceMoneyRecord();
        agentMoneyRecordEntity.setUserId(financeWithdrawalsApp.getUserId());
        agentMoneyRecordEntity.setChangeItem(FinanceMoneyRecord.CHANGE_ITEM_12);
        agentMoneyRecordEntity.setOperatorStyle(1);
        agentMoneyRecordEntity.setBriefing(briefing);
        agentMoneyRecordEntity.setChangeAmount(financeWithdrawalsApp.getAmount());
        agentMoneyRecordEntity.setBeforeAmount(agentMoneyTotal.getBalanceIncome());
        agentMoneyRecordEntity.setCurrentAmount(agentMoneyTotal.getBalanceIncome().add(financeWithdrawalsApp.getAmount()));
        agentMoneyRecordEntity.setCreateTime(DateUtils.getCurrentDate());
        agentMoneyRecordEntity.setModifyTime(DateUtils.getCurrentDate());
        financeMoneyRecordService.save(agentMoneyRecordEntity);
        //更新用戶鎖定金額
        agentMoneyTotal.setWithdrawLockMoney(agentMoneyTotal.getWithdrawLockMoney().subtract(financeWithdrawalsApp.getAmount()));
        agentMoneyTotal.setBalanceIncome(agentMoneyTotal.getBalanceIncome().add(financeWithdrawalsApp.getAmount()));
        //agentMoneyTotal.setIncomeInTotal(financeWithdrawalsApp.getAmount());
        //agentMoneyTotal.setLastRecordId(agentMoneyRecordEntity.getId());
        agentMoneyTotalService.updateById(agentMoneyTotal);
        updateById(financeWithdrawalsApp);
    }

    @Override
    public ExcelData export(Map<String, Object> params) {
        Page<FinanceWithdrawalsApp> page = new Page<>(1, Integer.MAX_VALUE);
        List<FinanceWithdrawalsApp> financeIncomeLogList = baseMapper.queryPage(page, params);
        ExcelData data = new ExcelData();
        data.setName("代理商提现申请");
        // 设置表头
        ArrayList<String> titles = new ArrayList<>();
        titles.add("提现单号");
        titles.add("代理商");
        titles.add("手机号");
        titles.add("提现金额");
        titles.add("提现方式");
        titles.add("收款账号");
        titles.add("收款账号名称");
        titles.add("状态");
        titles.add("拒绝原因");
        titles.add("审核时间");
        titles.add("申请时间");
        data.setTitles(titles);
        List<List<Object>> rows = new ArrayList<>();
        if (financeIncomeLogList != null && financeIncomeLogList.size() != 0) {
            for (FinanceWithdrawalsApp dataTemplate : financeIncomeLogList) {
                ArrayList<Object> row = new ArrayList<>();
                row.add(dataTemplate.getSn());
                row.add(dataTemplate.getName());
                row.add(dataTemplate.getMobile());
                row.add(dataTemplate.getAmount());
                row.add(dataTemplate.getMethodString());
                row.add(dataTemplate.getAccountNo());
                row.add(dataTemplate.getAccountName());
                row.add(dataTemplate.getStatusString());
                row.add(dataTemplate.getReason());
                row.add(DateUtils.format(dataTemplate.getOperateTime(), DateUtils.DATE_TIME_PATTERN));
                row.add(DateUtils.format(dataTemplate.getCreateTime(), DateUtils.DATE_TIME_PATTERN));
                rows.add(row);
            }
        }
        data.setRows(rows);
        return data;
    }
}
